package com._51doit.day01.xingge例子.adv;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 不使用Java8的Stream编程
 * 使用泛型定义一个更加高级的List
 *
 * 作用：通过这个例子让大家更加理解函数式编程，和深入理解泛型
 *
 * MyAdvList 要具备List的全部功能，并且可以扩展一些我想要的方法，比如map方法、filter方法、reduce方法等
 */
public class MyAdvList<T> extends ArrayList<T> {

    public MyAdvList<T> filter(MyFunction1<T, Boolean> func) {
        //定义一个新的List
        MyAdvList<T> nList = new MyAdvList<T>();
        //循环当前list中的数据
        for (T t : this) {
            //应用外部的过滤逻辑
            Boolean flag = func.apply(t);
            //将符合条件的数据添加到新的List中
            if (flag) {
                nList.add(t);
            }
        }
        //返回新的List
        return nList;
    }


    public <R> MyAdvList<R> map(MyFunction1<T, R> func) {
        //定义一个新的List
        MyAdvList<R> nList = new MyAdvList<>();
        //循环老的List
        for (T t : this) {
            //应用外部的运算逻辑
            R r = func.apply(t);
            //将新的元素加入到新的List中
            nList.add(r);
        }
        //返回新的List
        return nList;
    }

    public T reduce(MyFunction2<T, T, T> func) {
        //定义一个临时变量（初始值或中间累加的结果）
        T acc = null;
        boolean isFirst = true;
        //循环当前List
        for (T t : this) {
            if (isFirst) {
                acc = t;
                isFirst = false;
            } else {
                acc = func.apply(acc, t);
            }
        }
        //返回
        return acc;
    }

    public <R> MyAdvList<R> flatMap(MyFunction1<T, Iterator<R>> func) {
        //定义一个新的集合
        MyAdvList<R> nList = new MyAdvList<>();
        //遍历当前的集合
        for (T t : this) {
            Iterator<R> it = func.apply(t);
            while (it.hasNext()) {
                R r = it.next();
                nList.add(r);
            }
        }
        //返回新的List
        return nList;

    }
}
